package cn.zyq.ykb.service.user.impl;

import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.StrUtil;
import cn.zyq.ykb.beans.admin.Admin;
import cn.zyq.ykb.beans.config.ConfigBrokerage;
import cn.zyq.ykb.beans.product.ProductOrder;
import cn.zyq.ykb.beans.sys.SysAdmin;
import cn.zyq.ykb.beans.sys.SysAdminRole;
import cn.zyq.ykb.beans.task.bo.UserUpgradeBo;
import cn.zyq.ykb.beans.task.bo.UserUptTeamBo;
import cn.zyq.ykb.beans.user.User;
import cn.zyq.ykb.beans.user.UserBalance;
import cn.zyq.ykb.beans.user.UserCash;
import cn.zyq.ykb.beans.user.UserPromotion;
import cn.zyq.ykb.beans.user.bo.BindAlipayBo;
import cn.zyq.ykb.beans.user.bo.FillInviteCodeBo;
import cn.zyq.ykb.beans.user.bo.UserUptRatioBo;
import cn.zyq.ykb.beans.user.bo.WxLoginBo;
import cn.zyq.ykb.beans.user.dto.UserLoginDto;
import cn.zyq.ykb.beans.user.vo.GetUserNumberVo;
import cn.zyq.ykb.beans.user.vo.GetUserVo;
import cn.zyq.ykb.beans.user.vo.MyTem;
import cn.zyq.ykb.beans.user.vo.UserWalletDetailVo;
import cn.zyq.ykb.mapper.config.ConfigBrokerageMapper;
import cn.zyq.ykb.mapper.product.ProductOrderMapper;
import cn.zyq.ykb.mapper.sys.SysAdminMapper;
import cn.zyq.ykb.mapper.user.UserBalanceMapper;
import cn.zyq.ykb.mapper.user.UserCashMapper;
import cn.zyq.ykb.mapper.user.UserMapper;
import cn.zyq.ykb.mapper.user.UserPromotionMapper;
import cn.zyq.ykb.service.config.ConfigBrokerageService;
import cn.zyq.ykb.service.sys.SysAdminRoleService;
import cn.zyq.ykb.service.sys.SysAdminService;
import cn.zyq.ykb.service.user.UserService;
import cn.zyq.ykb.system.common.BaseService;
import cn.zyq.ykb.system.common.PageParam;
import cn.zyq.ykb.system.config.consts.redis.RedisH5Keys;
import cn.zyq.ykb.system.config.consts.system.RegularConst;
import cn.zyq.ykb.system.config.consts.system.SystemConfig;
import cn.zyq.ykb.system.config.redis.RedisService;
import cn.zyq.ykb.system.config.sms.SmsConfig;
import cn.zyq.ykb.system.config.weixin.WxConfig;
import cn.zyq.ykb.system.enums.core.*;
import cn.zyq.ykb.system.exception.BusinessException;
import cn.zyq.ykb.system.pay.core.client.PayClient;
import cn.zyq.ykb.system.pay.core.client.PayCommonResult;
import cn.zyq.ykb.system.pay.core.client.dto.PayOrderTransferReqDTO;
import cn.zyq.ykb.system.pay.core.client.dto.PayOrderTransferRespDTO;
import cn.zyq.ykb.system.pay.core.client.impl.alipay.AlipayPayClientConfig;
import cn.zyq.ykb.system.ry.util.SecurityUtils;
import cn.zyq.ykb.system.utils.MD5Util;
import cn.zyq.ykb.system.utils.Sample;
import cn.zyq.ykb.system.utils.VerifyCodeUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.tea.TeaModel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户表
 * 2023-04-02 09:09:22
 */

@Slf4j
@Service
public class UserServiceImpl extends BaseService implements UserService {
    @Autowired
    private RedisService redisService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserPromotionMapper userPromotionMapper;

    @Autowired
    private UserCashMapper userCashMapper;

    @Autowired
    private UserBalanceMapper userBalanceMapper;

    @Autowired
    private ConfigBrokerageMapper configBrokerageMapper;

    @Autowired
    private ConfigBrokerageService configBrokerageService;
    @Autowired
    private SysAdminService sysAdminService;
    @Autowired
    private SysAdminRoleService sysAdminRoleService;
    @Autowired
    private SysAdminMapper sysAdminMapper;
    @Autowired
    private ProductOrderMapper productOrderMapper;

    /**
     * 查询用户
     *
     * @param userID 用户主键
     * @return 用户
     */
    @Override
    public User selectUserByUserID(Integer userID) {
        User user = userMapper.selectByPrimaryKey(userID);
        if (user.getDeleted() == 1) {
            return null;
        }
        return user;
    }

    /**
     * 查询用户
     *
     * @param serviceID 业务ID
     * @return 用户
     */
    @Override
    public User selectUserByServiceID(String serviceID) {
        User param = new User();
        param.setDeleted(0);
        param.setServiceID(serviceID);
        return this.userMapper.selectOne(param);
    }

    /**
     * 查询用户列表
     *
     * @param pageParam
     * @param admin
     * @return 用户
     */
    @Override
    public PageInfo<User> selectUserList(PageParam pageParam, SysAdmin admin) {
        pageParam.getKv().put("deleted", 0);
        SysAdmin sysAdmin = this.sysAdminMapper.selectByPrimaryKey(admin.getSysAdminID());
        List<User> list = null;
        if (sysAdmin.getUserType().equals("01")) {
            User user2 = new User();
            user2.setDeleted(0);
            user2.setPhone(admin.getPhonenumber());
            User user3 = this.userMapper.selectOne(user2);
            pageParam.getKv().put("userID", user3.getUserID());
            PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
            list = this.userMapper.list1(pageParam.getKv());
        } else {
            PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
            list = this.userMapper.list(pageParam.getKv());
        }
        for (User user : list) {
            User user1 = this.userMapper.selectByPrimaryKey(user.getService());
            user.setFwsUser(user1);
        }
        return new PageInfo<>(list);
    }

    /**
     * 查询用户列表
     *
     * @param param
     * @return 用户
     */
    @Override
    public List<User> selectUserList(User param) {
        param.setDeleted(0);
        return this.userMapper.select(param);
    }

    /**
     * 新增用户
     *
     * @param param 用户
     * @return 结果
     */
    @Override
    public int insertUser(User param) {
        this.setCreateBaseData(param, SecurityUtils.getLoginUser().getSysAdmin());
        return this.userMapper.insertSelective(param);
    }

    /**
     * 修改用户
     *
     * @param param 用户
     * @return 结果
     */
    @Override
    public int updateUser(User param) {
        this.setUpdateBaseData(param, SecurityUtils.getLoginUser().getSysAdmin());
        return this.userMapper.updateByPrimaryKeySelective(param);
    }

    /**
     * 批量删除用户
     *
     * @param userIDs 需要删除的用户主键
     * @return 结果
     */
    @Override
    public int deleteUserByUserIDs(Integer[] userIDs) {
        int i = 0;
        for (Integer userID : userIDs) {
            i += this.deleteUserByUserID(userID);
        }
        return i;
    }

    /**
     * 删除用户信息
     *
     * @param userID 用户主键
     * @return 结果
     */
    @Override
    public int deleteUserByUserID(Integer userID) {
        User user = this.selectUserByUserID(userID);
        if (user == null) {
            return 0;
        } else {
            User storeInfo = new User();
            storeInfo.setUserID(userID);
            storeInfo.setDeleted(1);
            storeInfo.setUpdateBy(SecurityUtils.getSysAdminID());
            storeInfo.setUpdateTime(LocalDateTime.now());
            this.userMapper.updateByPrimaryKeySelective(storeInfo);
            return 1;
        }
    }

    @Override
    public String getCacheKey(String key) {
        return RedisH5Keys.SESSIONID_KEY(key);
    }

    @Override
    public User getFromCache(String key) {
        return this.redisService.getCacheObject(this.getCacheKey(key));
    }

    @Override
    public void setToCache(User user) {
        String cacheKey = this.getCacheKey(user.getToken());
        this.redisService.setCacheObject(cacheKey, user);
        this.redisService.expire(user.getToken(), SystemConfig.timeoutH5, TimeUnit.HOURS);
    }

    @Override
    public void deleteForCache(String key) {
        this.redisService.deleteObject(this.getCacheKey(key));
    }

    /**
     * 创建新的token，并更新到缓存、数据库中
     *
     * @param user
     * @return 返回新建的token
     */
    private String updateToken(User user) {
        User storeInfo = this.getUpdateInstance(User.class);
        storeInfo.setUserID(user.getUserID());
        String token = this.uuid();
        storeInfo.setToken(token);
        user.setToken(token);
        this.setToCache(user);
        this.userMapper.updateByPrimaryKeySelective(storeInfo);
        return token;
    }

    @Override
    public PageInfo<User> list(PageParam pageParam, Admin admin) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
        List<User> dbList = this.userMapper.list(pageParam.getKv());
        return new PageInfo<>(dbList);
    }

    @Override
    public void add(User param, Admin admin) {
        Integer id = param.getUserID();
        User addInfo = this.getCreateInstance(User.class, admin);
        addInfo.setUserID(id);
        this.userMapper.insertSelective(addInfo);
    }

    @Override
    public void update(User param, Admin admin) {
        Integer id = param.getUserID();
        User storeInfo = this.getUpdateInstance(User.class, admin);
        storeInfo.setUserID(id);
        this.userMapper.updateByPrimaryKeySelective(storeInfo);
    }

    @Override
    public void del(String serviceID, Admin admin) {
        User dbInfo = this.detail(serviceID);
        Integer id = dbInfo.getUserID();
        this.deleteLogic(id, admin, this.userMapper);
    }

    @Override
    public User detail(String serviceID, Admin admin) {
        return this.detail(serviceID);
    }

    @Override
    public User detail(String serviceID) {
        User dbInfo = this.getByServiceID(serviceID, User.class, this.userMapper);
        this.checkLogicExist(dbInfo);
        return dbInfo;
    }

    @Override
    public User detailByID(Integer userID) {
        return this.userMapper.selectByPrimaryKey(userID);
    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isNotBlank(token)) {
            User cacheInfo = this.getFromCache(token);
            if (cacheInfo != null) {
                this.setToCache(cacheInfo);
                return cacheInfo;
            }
            // 判断token是否存在，不存在要抛异常
            // if (StringUtils.isBlank(token)) {
            //     throw new BusinessException(ResponseCodeEnum.ERROR, "没有获取到登录凭证");
            // }
            // 用token查用户信息，查不到要抛异常
            User paramUser = new User();
            paramUser.setToken(token);
            User user = this.userMapper.selectOne(paramUser);
            // log.info("token不正确，请在网站上登录自己的帐号，然后进入个人设置页面扫描二维码获取token");
            if (user == null) {
                throw new BusinessException(ResponseCodeEnum.APP_NO_LOGIN);
            } else {
                //获取未读消息数量
                // user.setUnReadMsgNun(this.msgService.countUnReadMsg(user.getUserID()));
                return user;
            }
        } else {
            throw new BusinessException(ResponseCodeEnum.H5_NO_LOGIN);
        }
    }

    @Override
    public User wxLogin(WxLoginBo bo, HttpServletRequest request) {
        if (StringUtils.isBlank(bo.getCode())) {
            throw new BusinessException(ResponseCodeEnum.INVALID_PARAM);
        }
        log.info("前端code：{}", bo.getCode());
        String sessionKey = null;
        String openId = null;
        WxOAuth2UserInfo userInfo = new WxOAuth2UserInfo();
        try {
            WxOAuth2AccessToken accessToken = WxConfig.wxMpService().getOAuth2Service().getAccessToken(bo.getCode());
            userInfo = WxConfig.wxMpService().getOAuth2Service().getUserInfo(accessToken, null);
            openId = userInfo.getOpenid();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        if (StringUtils.isBlank(openId)) {
            log.error("微信登录,调用官方接口失败：{}", bo.getCode());
            throw new BusinessException(ResponseCodeEnum.ERROR, "调用微信方失败");
        }
        log.info("前端code：{}", openId);
        User paramUser = new User();
        paramUser.setWxAppOpenid(openId);
        paramUser.setDeleted(0);
        User user = this.userMapper.selectOne(paramUser);
        if (StringUtils.isNotEmpty(bo.getPhone())) {
            if (user != null && StringUtils.isNotBlank(user.getPhone())) {
                if (!user.getPhone().equals(bo.getPhone())) {
                    throw new BusinessException(ResponseCodeEnum.App_NO_LOGIN, "该微信已绑定其它手机号，请更换微信重新绑定");
                } else if (user.getPhone().equals(bo.getPhone())) {
                    throw new BusinessException("已绑定过手机号，不用重复绑定");
                }
            }
            User paramU = new User();
            paramU.setPhone(bo.getPhone());
            paramU.setDeleted(0);
            User user1 = this.userMapper.selectOne(paramU);
            user1.setWxAppOpenid(openId);
            user1.setAvatar(userInfo.getHeadImgUrl());
            user1.setNickName(userInfo.getNickname());
            this.userMapper.updateByPrimaryKeySelective(user1);
            if (user != null) {
                this.deleteLogic(user.getUserID(), this.userMapper);
                if (StringUtils.isNotBlank(user.getToken())) {
                    this.deleteForCache(user.getToken());
                }
            }
            return user1;
        } else {
            String token = this.uuid();
            if (user != null) {
                if (StringUtils.isEmpty(user.getPhone()) || user.getPosition() == null){
                    return user;
                }
                user.setToken(token);
                this.userMapper.updateByPrimaryKeySelective(user);
            } else {
                user = new User();
                user.setWxAppOpenid(openId);
                user.setAvatar(userInfo.getHeadImgUrl());
                user.setNickName(userInfo.getNickname());
                this.setCreateBaseData(user, new User());
                this.userMapper.insertSelective(user);
            }
            return user;
        }
    }

    @Override
    public Object getPhone(String code, User loginUser) {
        log.info("【请求开始】绑定手机号码,请求参数，code:{}", code);
        WxMaPhoneNumberInfo phoneNumberInfo = null;
        try {
            phoneNumberInfo = WxConfig.wxMaService().getUserService().getPhoneNoInfo(code);
        } catch (Exception e) {
            log.error("获取手机号码失败,获取微信绑定的手机号码出错：{}", code);
            log.error(e.getMessage(), e);
            throw new BusinessException(ResponseCodeEnum.ERROR, "通过微信获取手机号失败");
        }
        String phone = phoneNumberInfo.getPhoneNumber();
        User updateInstance = this.getUpdateInstance(User.class, loginUser);
        updateInstance.setPhone(phone);
        if (this.userMapper.updateByPrimaryKeySelective(updateInstance) == 0) {
            log.error("获取手机号码,更新用户信息出错,id：{}", loginUser.getUserID());
            throw new BusinessException(ResponseCodeEnum.ERROR, "手机号码更新失败");
        }
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("phone", phone);

        log.info("【请求结束】绑定手机号码,响应结果：{}", JSONObject.toJSONString(data));
        return this.userMapper.selectByPrimaryKey(loginUser.getUserID());
    }

    @Override
    public User updateInfo(User loginUser, User user) {
        log.info("【请求开始】修改用户信息,请求参数,loginUser:{},user:{}", loginUser, user);
        User updateInfo = new User();
        updateInfo.setUserID(loginUser.getUserID());
        updateInfo.setNickName(user.getNickName());
        updateInfo.setAvatar(user.getAvatar());
        int i = this.userMapper.updateByPrimaryKeySelective(updateInfo);
        if (i == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "用户信息更新失败");
        }
        return this.userMapper.selectByPrimaryKey(loginUser.getUserID());
    }


    @Override
    public int addWallet(BigDecimal amount, Integer userID) {
        return this.userMapper.updateWallet(amount, userID);
    }

    @Override
    public int subWallet(BigDecimal amount, Integer userID) {
        return this.userMapper.subWallet(amount, userID);
    }

    @Override
    public User smsLogin(UserLoginDto dto) {
        if (StrUtil.isEmpty(dto.getPhone())
                || dto.getPhone().length() != 11
                || !dto.getPhone().matches(RegularConst.PHONE_RULE)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "没有获取到正确的手机号");
        }

        User user = new User();
        user.setPhone(dto.getPhone());
        user.setDeleted(0);
        User user1 = this.userMapper.selectOne(user);
//        if (dto.getPhone().equals("17381570019")){
//            if(!MD5Util.encode(dto.getSmsCode()).equals(user1.getPassword())){
//                throw new BusinessException(ResponseCodeEnum.ERROR, "账号密码不正确，请重新输入");
//            }
//            this.deleteForCache(user1.getToken());
//            user1.setToken(this.uuid());
//            this.setToCache(user1);
//            this.userMapper.updateByPrimaryKeySelective(user1);
//            return user1;
//        }
        if (BeanUtil.isEmpty(user1)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "该手机号未注册，请走新用户注册");
        }
        if (BeanUtil.isEmpty(dto.getSmsCode())) {
            throw new BusinessException(ResponseCodeEnum.NULL_VALUE, "短信验证码不能为空");
        }
        String smsCodeKey = RedisH5Keys.SMSCODE_KEY(dto.getPhone());
        String existedSmsCode = redisService.getCacheObject(smsCodeKey);
        //校验验证码
        if (StringUtils.isEmpty(existedSmsCode)) {
            throw new RuntimeException("短信验证码不存在或已过期");
        }
        if (!existedSmsCode.equals(dto.getSmsCode())) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "短信验证码输入错误");
        }
        this.deleteForCache(user1.getToken());
        user1.setToken(this.uuid());
        this.setToCache(user1);
        this.userMapper.updateByPrimaryKeySelective(user1);
        //最后清理下验证码
        if (redisService.hasKey(smsCodeKey)) {
            this.deleteForCache(smsCodeKey);
        }
        return user1;
    }

    @Override
    public User person(String phone, HttpServletRequest request) {
        String token = request.getHeader("token");
        User user = new User();
        user.setPhone(phone);
        User user1 = this.userMapper.selectOne(user);
        if (!user1.getToken().equals(token)){
            throw new BusinessException(ResponseCodeEnum.APP_NO_LOGIN);
        }else {
            return user1;
        }
    }

    @Override
    public int updateHead(User user, User loginUser) {
        this.setUpdateBaseData(user, loginUser);
        return this.userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public User getResidue(User loginUser) {
        User user = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        return user;
    }

    @Override
    public Integer smsCode(String phone) {
        if (StrUtil.isEmpty(phone) || phone.length() != 11 || !phone.matches(RegularConst.PHONE_RULE)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "没有获取到正确的手机号");
        }

        String smsCodeKey = RedisH5Keys.SMSCODE_KEY(phone);
        String existedSmsCode = redisService.getCacheObject(smsCodeKey);
        String smsCode = this.getSmsVerifyCode();
        //如果验证码已存在
        if (StringUtils.isNotEmpty(existedSmsCode)) {
            Long expireTime = redisService.redisTemplate.opsForValue().getOperations().getExpire(smsCodeKey);
            long lastTime = 60 * 3 - expireTime;
            //三分钟内验证码有效，1分钟到3分钟之间，用户可以继续输入验证码，也可以重新获取验证码，新的验证码将覆盖旧的
            if (lastTime > 60 && expireTime > 0) {
                //调用第三方平台发短信，只有短信发送成功了，才能将短信验证码保存到redis
                log.info("此处调用短信发送逻辑......");
                this.sendAliSms(phone, smsCode);
                redisService.redisTemplate.opsForValue().set(smsCodeKey, smsCode, 60 * 3, TimeUnit.SECONDS);
                log.info("短信验证码：{}", smsCode);
            }
            //一分钟之内不得多次获取验证码
            if (lastTime < 60) {
                throw new BusinessException(ResponseCodeEnum.ERROR, "操作过于频繁，请一分钟之后再次点击发送");
            }
            return 1;
        } else {
            //发送短信验证码
            log.info("验证码不存在，重新调用");
            this.sendAliSms(phone, smsCode);
            log.info("短信验证码：{}", smsCode);
            redisService.redisTemplate.opsForValue().set(smsCodeKey, smsCode, 60 * 3, TimeUnit.SECONDS);
            return 1;
        }
    }

    @Override
    @Transactional
    public User bindPhone(UserLoginDto dto) {
        log.info("绑定手机号入参：{}", dto);
        if (StrUtil.isEmpty(dto.getPhone())
                || dto.getPhone().length() != 11
                || !dto.getPhone().matches(RegularConst.PHONE_RULE)) {
            throw new BusinessException(ResponseCodeEnum.NULL_VALUE, "没有获取到正确的手机号");
        }
        if (StringUtils.isEmpty(dto.getCode())) {
            throw new BusinessException(ResponseCodeEnum.NULL_VALUE, "邀请码不能为空");
        }
        if (StringUtils.isEmpty(dto.getSmsCode())) {
            throw new BusinessException(ResponseCodeEnum.NULL_VALUE, "短信验证码不能为空");
        }
        User user1 = new User();
        user1.setPhone(dto.getPhone());
        user1.setDeleted(0);
        User user = this.userMapper.selectOne(user1);
        if (BeanUtil.isNotEmpty(user)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "该手机号已注册请直接登录");
        }
        //根据code查询邀请人信息
        User user2 = new User();
        user2.setCode(dto.getCode());
        user2.setDeleted(0);
        User user3 = this.userMapper.selectOne(user2);

        //根据钻石邀请码查询
        User userSelect = new User();
        userSelect.setZsCode(dto.getCode());
        userSelect.setDeleted(0);
        User userZs = this.userMapper.selectOne(userSelect);

        //获取验证码
        String smsCodeKey = RedisH5Keys.SMSCODE_KEY(dto.getPhone());
        String existedSmsCode = redisService.getCacheObject(smsCodeKey);
        //校验验证码
        if (StringUtils.isEmpty(existedSmsCode)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "短信验证码不存在或已过期");
        }
        if (!existedSmsCode.equals(dto.getSmsCode())) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "短信验证码输入错误");
        }

        User insertUser = new User();
        insertUser.setPhone(dto.getPhone());
        insertUser.setInviteNum(0);
        insertUser.setNickName(dto.getPhone());

        UserPromotion pro = new UserPromotion();
        pro.setDeleted(0);
        if (BeanUtil.isNotEmpty(user3)) {
            insertUser.setInviteUserID(user3.getUserID());
            insertUser.setPosition(UserPositionEnum.PT.getValue());
            insertUser.setCode(VerifyCodeUtil.generateVerifyCode(6));
            if (user3.getPosition().equals(UserPositionEnum.FWS.getValue())) {
                insertUser.setService(user3.getUserID());

                pro.setPUser(user3.getUserID());
//                pro.setUserID(user3.getInviteUserID());

                //修改状态为已推广
                UserPromotion userPromotion1 = this.userPromotionMapper.selectOne(pro);
                userPromotion1.setStatus(1);
                this.userPromotionMapper.updateByPrimaryKeySelective(userPromotion1);
            } else if (user3.getPosition().equals(UserPositionEnum.TDZ.getValue())) {
                insertUser.setTeamLeader(user3.getUserID());
                insertUser.setService(user3.getService());

                pro.setPUser(user3.getUserID());
//                pro.setUserID(user3.getInviteUserID());

                //修改状态为已推广
                UserPromotion userPromotion1 = this.userPromotionMapper.selectOne(pro);
                userPromotion1.setStatus(1);
                this.userPromotionMapper.updateByPrimaryKeySelective(userPromotion1);
            } else if (user3.getPosition().equals(UserPositionEnum.GR.getValue())){
                insertUser.setPerson(user3.getUserID());

                pro.setPUser(user3.getUserID());
//                pro.setUserID(user3.getInviteUserID());

                //修改状态为已推广
                UserPromotion userPromotion1 = this.userPromotionMapper.selectOne(pro);
                userPromotion1.setStatus(1);
                this.userPromotionMapper.updateByPrimaryKeySelective(userPromotion1);

            }else {
                insertUser.setTeamLeader(user3.getTeamLeader());
                insertUser.setService(user3.getService());
            }
            //绑定成功后新增用户推广数量，以及用户推广表数据
            user3.setInviteNum(user3.getInviteNum() + 1);
            this.userMapper.updateByPrimaryKeySelective(user3);


        } else if (BeanUtil.isNotEmpty(userZs)) {
//            pro.setPUser(userZs.getUserID());
//            pro.setUserID(userZs.getInviteUserID());

            insertUser.setInviteUserID(userZs.getUserID());
            insertUser.setPosition(UserPositionEnum.ZS.getValue());
            insertUser.setZsCode(VerifyCodeUtil.generateVerifyCode(6));
            insertUser.setService(userZs.getUserID());
            //绑定成功后新增用户推广数量，以及用户推广表数据
            userZs.setInviteNum(userZs.getInviteNum() + 1);
            this.userMapper.updateByPrimaryKeySelective(userZs);
        } else {
            throw new BusinessException(ResponseCodeEnum.ERROR, "邀请人信息不存在");
        }
//        this.setToCache(insertUser);
        this.setCreateBaseData(insertUser, new User());
        this.userMapper.insertSelective(insertUser);
        //新增推广表数据
        UserPromotion userPromotion = new UserPromotion();
        userPromotion.setPUser(insertUser.getUserID());
        userPromotion.setState(UserPromotionEnum.ON.getValue());
        userPromotion.setStatus(UserPromotionEnum.ON.getValue());
        if (BeanUtil.isNotEmpty(user3)) {
            userPromotion.setPromotionType(UserPromotionEnum.OFF.getValue());
            userPromotion.setUserID(user3.getUserID());
            userPromotion.setPosition(UserPositionEnum.PT.getValue());
        } else {
            userPromotion.setPromotionType(UserPromotionEnum.ON.getValue());
            userPromotion.setUserID(userZs.getUserID());
            userPromotion.setPosition(UserPositionEnum.ZS.getValue());
        }
        this.setCreateBaseData(userPromotion, new User());
        this.userPromotionMapper.insertSelective(userPromotion);
        //最后清理下验证码
        if (redisService.hasKey(smsCodeKey)) {
            redisService.deleteObject(smsCodeKey);
        }
        return insertUser;
    }

    @Override
    public User fillInviteCode(FillInviteCodeBo bo) {
        User user = this.userMapper.selectByPrimaryKey(bo.getUserID());
        if (BeanUtil.isEmpty(user)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "当前用户新增失败");
        }
        //查看是否已填写过邀请码
        if (user.getInviteUserID() > 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "不能重复接受邀请");
        }
        User user1 = new User();
        user1.setPhone(bo.getPhone());
        user1.setDeleted(0);
        User user2 = this.userMapper.selectOne(user1);
        if (BeanUtil.isNotEmpty(user2)) {
//            user2.setWxAppOpenid(user.getWxAppOpenid());
            this.userMapper.deleteByPrimaryKey(bo.getUserID());
            throw new BusinessException(ResponseCodeEnum.ERROR, "该手机号已注册不能重复使用");
        }
        //获取邀请人信息
        User paramUser = new User();
        paramUser.setCode(bo.getCode());
        paramUser.setDeleted(0);
        User inviteUser = this.userMapper.selectOne(paramUser);

        User zsUser = new User();
        zsUser.setZsCode(bo.getCode());
        zsUser.setDeleted(0);
        User userZs = this.userMapper.selectOne(zsUser);

        if (inviteUser == null && userZs == null) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "邀请人不存在");
        }

        //修改用户的推广表数据
        UserPromotion pro = new UserPromotion();
        pro.setDeleted(0);

        //根据手机号获取用户信息
        user.setPhone(bo.getPhone());
        //记录邀请人信息
//        user.setInviteUserID(inviteUser.getUserID());
        if (inviteUser == null) {
//            pro.setUserID(userZs.getInviteUserID());
//            pro.setPUser(userZs.getUserID());
            //如果是钻石邀请，只需要填写服务商
            user.setService(userZs.getUserID());
            user.setInviteUserID(userZs.getUserID());
            user.setPosition(UserPositionEnum.ZS.getValue());
            user.setZsCode(VerifyCodeUtil.generateVerifyCode(6));

            userZs.setInviteNum(userZs.getInviteNum() + 1);
            this.userMapper.updateByPrimaryKeySelective(userZs);
        } else {
            if (inviteUser.getPosition().equals(UserPositionEnum.PT.getValue())) {
                user.setService(inviteUser.getService());
                if (!inviteUser.getTeamLeader().equals(0)) {
                    user.setTeamLeader(inviteUser.getTeamLeader());
                }
                pro.setPUser(inviteUser.getUserID());
//                pro.setUserID(inviteUser.getInviteUserID());
                //修改状态为已推广
                UserPromotion userPromotion1 = this.userPromotionMapper.selectOne(pro);
                userPromotion1.setStatus(1);
                this.userPromotionMapper.updateByPrimaryKeySelective(userPromotion1);
            } else if (inviteUser.getPosition().equals(UserPositionEnum.TDZ.getValue())) {
                user.setService(inviteUser.getService());
                user.setTeamLeader(inviteUser.getUserID());

                pro.setPUser(inviteUser.getUserID());
//                pro.setUserID(inviteUser.getInviteUserID());
                //修改状态为已推广
                UserPromotion userPromotion1 = this.userPromotionMapper.selectOne(pro);
                userPromotion1.setStatus(1);
                this.userPromotionMapper.updateByPrimaryKeySelective(userPromotion1);
            } else if (inviteUser.getPosition().equals(UserPositionEnum.GR.getValue())){
                user.setPerson(inviteUser.getUserID());
                pro.setPUser(inviteUser.getUserID());
//                pro.setUserID(inviteUser.getInviteUserID());
                //修改状态为已推广
                UserPromotion userPromotion1 = this.userPromotionMapper.selectOne(pro);
                userPromotion1.setStatus(1);
                this.userPromotionMapper.updateByPrimaryKeySelective(userPromotion1);
            }
            else {
                user.setService(inviteUser.getUserID());
            }
            //记录邀请人信息
            user.setInviteUserID(inviteUser.getUserID());
            user.setPosition(UserPositionEnum.PT.getValue());
            user.setCode(VerifyCodeUtil.generateVerifyCode(6));

            inviteUser.setInviteNum(inviteUser.getInviteNum() + 1);
            this.userMapper.updateByPrimaryKeySelective(inviteUser);


        }
        user.setToken(this.uuid());
        this.setUpdateBaseData(user, user);
        this.userMapper.updateByPrimaryKeySelective(user);

        //新增推广表数据
        UserPromotion userPromotion = new UserPromotion();
        userPromotion.setPUser(bo.getUserID());
        userPromotion.setState(2);
        userPromotion.setStatus(2);
        userPromotion.setContribute(new BigDecimal(0));
        userPromotion.setRealReturn(new BigDecimal(0));
        if (inviteUser == null) {
            userPromotion.setUserID(userZs.getUserID());
            userPromotion.setPosition(UserPositionEnum.ZS.getValue());
            userPromotion.setPromotionType(UserPositionEnum.ZS.getValue());
        } else {
            userPromotion.setUserID(inviteUser.getUserID());
            userPromotion.setPosition(UserPositionEnum.PT.getValue());
            userPromotion.setPromotionType(UserPositionEnum.PT.getValue());
        }
        user = this.userMapper.selectByPrimaryKey(user.getUserID());
        this.setToCache(user);
        this.setCreateBaseData(userPromotion, user);
        this.userPromotionMapper.insertSelective(userPromotion);
        return user;
    }

    @Override
    public User updatePhone(UserLoginDto dto, User loginUser) {
        User user1 = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        if (StrUtil.isEmpty(dto.getPhone())
                || dto.getPhone().length() != 11
                || !dto.getPhone().matches(RegularConst.PHONE_RULE)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "没有获取到正确的手机号");
        }
        User userParam = new User();
        userParam.setPhone(dto.getPhone());
        userParam.setDeleted(0);
        User user = this.userMapper.selectOne(userParam);
        if (BeanUtil.isNotEmpty(user)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "该手机号已被其它用户绑定");
        }
        String smsCodeKey = RedisH5Keys.SMSCODE_KEY(dto.getPhone());
        String existedSmsCode = redisService.getCacheObject(smsCodeKey);
        //校验验证码
        if (StringUtils.isEmpty(existedSmsCode)) {
            throw new RuntimeException("短信验证码不存在或已过期");
        }
        if (!existedSmsCode.equals(dto.getSmsCode())) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "短信验证码输入错误");
        }
        User updateUser = this.getUpdateInstance(User.class, user1);
        updateUser.setUserID(user1.getUserID());
        updateUser.setPhone(dto.getPhone());
        this.userMapper.updateByPrimaryKeySelective(updateUser);
        //最后清理下验证码
        if (redisService.hasKey(smsCodeKey)) {
            redisService.deleteObject(smsCodeKey);
        }
        return updateUser;
    }

    @Override
    public int uptName(User user, User loginUser) {
        if (StringUtils.isEmpty(user.getNickName())) {
            throw new BusinessException(ResponseCodeEnum.NULL_VALUE, "昵称不能为空");
        }
        User userParam = new User();
        userParam.setNickName(user.getNickName());
        userParam.setDeleted(0);
        User user1 = this.userMapper.selectOne(userParam);
        if (BeanUtil.isNotEmpty(user1)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "该昵称已经有其它用户在使用");
        }
        User user2 = this.userMapper.selectByPrimaryKey(user.getUserID());
        user2.setNickName(user.getNickName());
        this.setUpdateBaseData(user2, loginUser);
        int i = this.userMapper.updateByPrimaryKeySelective(user2);
        if (i == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "修改昵称失败");
        }
        return 1;
    }

    @Override
    public User bindAlipay(BindAlipayBo bo, User loginUser) {
        if (StrUtil.isBlank(bo.getName())) {
            throw new BusinessException("账户姓名不能为空");
        }
        if (StrUtil.isBlank(bo.getAliAccount())) {
            throw new BusinessException("账户不能为空");
        }
        if (StrUtil.isBlank(bo.getPhone())) {
            throw new BusinessException("手机号码不能为空");
        }
        if (StrUtil.isBlank(bo.getSmsCode())) {
            throw new BusinessException("短信验证码不能为空");
        }
        // 校验短信验证码
        String smsCodeKey = RedisH5Keys.SMSCODE_KEY(bo.getPhone());
        String existedSmsCode = redisService.getCacheObject(smsCodeKey);
        //校验验证码
        if (StringUtils.isEmpty(existedSmsCode)) {
            throw new RuntimeException("短信验证码不存在或已过期");
        }
        if (!existedSmsCode.equals(bo.getSmsCode())) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "短信验证码输入错误");
        }
        User userParam = new User();
        userParam.setAliAccount(bo.getAliAccount());
        userParam.setDeleted(0);
        User user = this.userMapper.selectOne(userParam);
        if (BeanUtil.isNotEmpty(user)) {
            if (!user.getUserID().equals(loginUser.getUserID())){
                throw new BusinessException(ResponseCodeEnum.ERROR, "该支付宝账号已被其它人绑定");
            }
        }
        User updateUser = this.getUpdateInstance(User.class, loginUser);
        updateUser.setAliAccount(bo.getAliAccount());
        updateUser.setAccountName(bo.getName());
        updateUser.setUserID(loginUser.getUserID());
        // this.setUpdateBaseData(loginUser,loginUser);
        this.userMapper.updateByPrimaryKeySelective(updateUser);
        //最后清理下验证码
        if (redisService.hasKey(smsCodeKey)) {
            redisService.deleteObject(smsCodeKey);
        }
        return loginUser;
    }

    @Override
    public User getWxCode(User loginUser) {
        User user = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        if (BeanUtil.isEmpty(user)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "当前用户信息不存在");
        }
        //获取当前用户的推广人信息
        User user1 = this.userMapper.selectByPrimaryKey(user.getInviteUserID());
        if (BeanUtil.isEmpty(user1)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "邀请人信息不存在");
        }
        return user1;
    }

    @Override
    public PageInfo<User> getMyTeam(PageParam pageParam, User loginUser) {
        pageParam.getKv().put("deleted", 0);
        User user1 = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        Integer type = (Integer) pageParam.getKv().get("type");
        UserPromotion userPromotion = new UserPromotion();
        userPromotion.setUserID(user1.getUserID());
        //直接团队
        if (type.equals(1)) {
            PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
            List<UserPromotion> select = this.userPromotionMapper.select(userPromotion);
            List<User> users = new ArrayList<>();
            for (UserPromotion promotion : select) {
                User user = this.userMapper.selectByPrimaryKey(promotion.getPUser());
                users.add(user);
            }
            return new PageInfo<>(users);
            //间接团队
        } else if (type.equals(2)) {
            //获取到所有直接用户ID
            List<UserPromotion> select = this.userPromotionMapper.select(userPromotion);
            //递归查询所有间接用户
            List<Integer> userIDList = new ArrayList<>();
            for (UserPromotion promotion : select) {
                this.queryUserID(userIDList, promotion.getPUser());
            }
//            List<UserPromotion> userPromotions = new ArrayList<>();
//            for (UserPromotion promotion : select) {
//                UserPromotion userPromotion1 = new UserPromotion();
//                userPromotion1.setUserID(promotion.getPUser());
//                List<UserPromotion> select1 = this.userPromotionMapper.select(userPromotion1);
//                for (UserPromotion userPromotion2 : select1) {
//                    userPromotions.add(userPromotion2);
//                }
//            }
//            List<User> users = new ArrayList<>();
//            for (UserPromotion promotion : userPromotions) {
//                User user = this.userMapper.selectByPrimaryKey(promotion.getPUser());
//                users.add(user);
//            }
            List<User> users = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(userIDList)) {
                Example example = new Example(User.class);
                example.createCriteria().andIn("userID", userIDList);
                example.orderBy("userID").desc();
                PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
                users = userMapper.selectByExample(example);
            }
            return new PageInfo<>(users);
        } else {
            User user2 = new User();
            user2.setPosition(3);
            user2.setService(loginUser.getUserID());
            user2.setDeleted(0);
            List<User> select1 = this.userMapper.select(user2);
            return new PageInfo<>(select1);
        }
    }

    /**
     * 获取间接推广人ID列表
     *
     * @param userIDList
     * @param userID
     * @return
     */
    @Override
    public List<Integer> queryUserID(List<Integer> userIDList, Integer userID) {
        UserPromotion userPromotion = new UserPromotion();
        userPromotion.setUserID(userID);
        userPromotion.setDeleted(0);
        List<UserPromotion> select = this.userPromotionMapper.select(userPromotion);
        if (CollectionUtil.isNotEmpty(select)) {
            for (UserPromotion promotion : select) {
                userIDList.add(promotion.getPUser());
                this.queryUserID(userIDList, promotion.getPUser());
            }
        }
        return userIDList;
    }

    @Override
    @Transactional
    public UserCash withdraw(UserCash param, User loginUser, HttpServletRequest request) {
        try {
            //10 代表10秒这个key直接过期
            if (redisService.redisTemplate.opsForValue().setIfAbsent("SysUserLock"+loginUser.getUserID(), loginUser.getUserID(), Duration.ofSeconds(10))) {
                //检查参数
                if (StringUtils.isBlank(param.getPrice().toString())) {
                    throw new BusinessException("请输入提现金额");
                }
                User user = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
                if (StringUtils.isBlank(user.getAliAccount())) {
                    throw new BusinessException("未绑定支付宝账号，请先绑定支付宝");
                }
                if (param.getPrice().compareTo(user.getWallet()) > 0) {
                    throw new BusinessException("钱包余额不足");
                }
                //修改用户钱包余额
                User updateInstance = this.getUpdateInstance(User.class);
                updateInstance.setUserID(loginUser.getUserID());
                updateInstance.setWallet(user.getWallet().subtract(param.getPrice()));
                this.setUpdateBaseData(updateInstance, loginUser);
                this.userMapper.updateByPrimaryKeySelective(updateInstance);
                //新增提现记录表
                param.setUserID(loginUser.getUserID());
                param.setState(AuditTypeEnum.AUDITING.getValue());
                param.setCashName(user.getNickName());
                param.setCashAccount(user.getAliAccount());
                this.setCreateBaseData(param, loginUser);
                int i = this.userCashMapper.insertSelective(param);
                if (i == 0) {
                    throw new BusinessException("新增提现记录失败");
                }

                PayOrderTransferReqDTO dto = new PayOrderTransferReqDTO();
                String userIP = request.getRemoteAddr();
                dto.setUserIp(userIP);
                dto.setNotifyUrl(null);
                dto.setUserAccount(user.getAliAccount());
                dto.setUname(user.getAccountName());
                dto.setOutTradeNo(param.getServiceID());
                dto.setTitle("悦推客App提现");
                dto.setAmount(MathUtil.yuanToCent(param.getPrice().doubleValue()));
                log.info("组装提现参数 {}", dto);
                PayClient client = AlipayPayClientConfig.getPayClientByChannelId(param.getChannelId());
                PayCommonResult<PayOrderTransferRespDTO> result  = client.unifiedTransfer(dto);
                log.info("提现结束 {}", result);
                PayOrderTransferRespDTO data = result.getData();
                if (data.getTradeStatus().equals("false")){
                    throw new BusinessException("提现失败"+ result.getApiMsg());
                }
                //新增余额变更记录
                UserBalance userBalance = new UserBalance(
                        loginUser.getUserID(),
                        user.getWallet().subtract(param.getPrice()),
                        user.getWallet(),
                        param.getPrice(),
                        param.getUserCashID(),
                        UserBalanceStatusEnum.TX.getValue(),
                        user.getUserID(),
                        "申请提现"
                );
                this.setCreateBaseData(userBalance,loginUser);
                this.userBalanceMapper.insertSelective(userBalance);
            }
        }finally {
            // 解锁
            redisService.redisTemplate.delete("SysUserLock"+loginUser.getUserID());
        }
        return param;
    }

    @Override
    public List<User> getService() {
        User user = new User();
        user.setPosition(UserPositionEnum.FWS.getValue());
        user.setDeleted(0);
        List<User> select = this.userMapper.select(user);
        return select;
    }

    @Override
    public int upgrade(UserUpgradeBo bo, SysAdmin loginAdmin) {
        User user = this.userMapper.selectByPrimaryKey(bo.getUserID());
        if (BeanUtil.isEmpty(user)) {
            throw new BusinessException("该用户不存在");
        }
        if (user.getPosition().equals(bo.getState())) {
            throw new BusinessException("当前用户已是该级别");
        }
        //查询上级服务商信息
        User user1 = this.userMapper.selectByPrimaryKey(user.getService());

        UserPromotion promotion = new UserPromotion();
        promotion.setPUser(user.getUserID());
        promotion.setDeleted(0);
        UserPromotion userPromotion = this.userPromotionMapper.selectOne(promotion);
        if (BeanUtil.isEmpty(userPromotion)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "用户推广表数据异常");
        }
        UserPromotion updateInstance = this.getUpdateInstance(UserPromotion.class);
        updateInstance.setUserPromotionID(userPromotion.getUserPromotionID());
        if (bo.getState().equals(UserPositionEnum.PT.getValue())) {
            if (!user.getPosition().equals(UserPositionEnum.ZS.getValue())) {
                throw new BusinessException("该用户不是钻石用户不能升级为初级用户");
            }
            user.setPosition(UserPositionEnum.PT.getValue());
            user.setCode(VerifyCodeUtil.generateVerifyCode(6));
            updateInstance.setPosition(UserPositionEnum.PT.getValue());
            updateInstance.setPromotionType(UserPositionEnum.PT.getValue());
        } else if (bo.getState().equals(UserPositionEnum.TDZ.getValue())) {
            if (user.getPosition().equals(2)) {
                user.setCode(VerifyCodeUtil.generateVerifyCode(6));
                updateInstance.setPromotionType(UserPositionEnum.PT.getValue());
            }
            user.setPosition(UserPositionEnum.TDZ.getValue());
            user.setTeamLeader(0);
            updateInstance.setPosition(UserPositionEnum.TDZ.getValue());
            user1.setLeftNumber(user1.getLeftNumber() - 1);
            this.userMapper.updateByPrimaryKeySelective(user1);
        } else if (bo.getState().equals(UserPositionEnum.FWS.getValue())) {
            if (user.getPosition().equals(2)){
                user.setCode(VerifyCodeUtil.generateVerifyCode(6));
            }else{
                user.setZsCode(VerifyCodeUtil.generateVerifyCode(6));
            }
            user.setPosition(UserPositionEnum.FWS.getValue());
            user.setTeamLeader(0);
            user.setService(0);
            user.setTdzNumber(50);
            user.setLeftNumber(50);
//            user.setZsCode(VerifyCodeUtil.generateVerifyCode(6));
            configBrokerageService.add(user);
            //升级成服务商后，可以登录管理端,初始密码123456，类型为01
            SysAdmin sysAdmin = new SysAdmin();
            sysAdmin.setUserName(user.getPhone());
            sysAdmin.setNickName(user.getNickName());
            sysAdmin.setUserType(AdminUserTypeEnum.FWSYH.getValue());
            sysAdmin.setPhonenumber(user.getPhone());
            if (StrUtil.isNotEmpty(user.getAvatar())) {
                sysAdmin.setAvatar(user.getAvatar());
            }
            sysAdmin.setPassword(SecurityUtils.encryptPassword("123456"));
            this.sysAdminService.add(sysAdmin, loginAdmin);

            SysAdminRole sysAdminRole = new SysAdminRole();
            sysAdminRole.setSysAdminID(sysAdmin.getSysAdminID());
            sysAdminRole.setSysRoleID(3);
            this.sysAdminRoleService.add(sysAdminRole, loginAdmin);
            updateInstance.setPosition(UserPositionEnum.FWS.getValue());
            updateInstance.setPromotionType(UserPositionEnum.PT.getValue());
        }else if (bo.getState().equals(UserPositionEnum.GR.getValue())){
            if (user.getPosition().equals(2)){
                user.setCode(VerifyCodeUtil.generateVerifyCode(6));
            }else{
                user.setZsCode(VerifyCodeUtil.generateVerifyCode(6));
            }
            user.setPosition(UserPositionEnum.GR.getValue());
            user.setTeamLeader(0);
            user.setService(0);
            user.setTdzNumber(50);
            user.setLeftNumber(50);

            //升级个人后 新增佣金表数据  用户数据为30-50
            ConfigBrokerage insert = new ConfigBrokerage();
            insert.setUserID(user.getUserID());
            insert.setType(0);
            insert.setDefaultUserProportion(30);
            insert.setDefaultCaptainProportion(0);
            insert.setCaptainMin(0);
            insert.setCaptainProportion(0);
            insert.setUserMin(30);
            insert.setUserMax(50);
            this.setCreateBaseData(insert,user);
            int i = this.configBrokerageMapper.insertSelective(insert);
            if (i == 0){
                throw new BusinessException(ResponseCodeEnum.ERROR,"新增个人佣金表失败");
            }

            //升级成个人后，可以登录管理端,初始密码123456，类型为01
            SysAdmin sysAdmin = new SysAdmin();
            sysAdmin.setUserName(user.getPhone());
            sysAdmin.setNickName(user.getNickName());
            sysAdmin.setUserType(AdminUserTypeEnum.FWSYH.getValue());
            sysAdmin.setPhonenumber(user.getPhone());
            if (StrUtil.isNotEmpty(user.getAvatar())) {
                sysAdmin.setAvatar(user.getAvatar());
            }
            sysAdmin.setPassword(SecurityUtils.encryptPassword("123456"));
            this.sysAdminService.add(sysAdmin, loginAdmin);

            SysAdminRole sysAdminRole = new SysAdminRole();
            sysAdminRole.setSysAdminID(sysAdmin.getSysAdminID());
            sysAdminRole.setSysRoleID(3);
            this.sysAdminRoleService.add(sysAdminRole, loginAdmin);
            updateInstance.setPosition(UserPositionEnum.GR.getValue());
            updateInstance.setPromotionType(UserPositionEnum.PT.getValue());
        }else {
            throw new BusinessException("没有该级别");
        }
        this.userPromotionMapper.updateByPrimaryKeySelective(updateInstance);
        this.setUpdateBaseData(user, loginAdmin);
        int i = this.userMapper.updateByPrimaryKeySelective(user);
        if (i == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "升级失败");
        }
        return 1;
    }

    @Override
    public int uptTeam(UserUptTeamBo bo, SysAdmin loginAdmin) {
        User user = this.userMapper.selectByPrimaryKey(bo.getUserID());
        if (BeanUtil.isEmpty(user)) {
            throw new BusinessException("该用户不存在");
        }
        User userService = this.userMapper.selectByPrimaryKey(bo.getService());
        if (BeanUtil.isEmpty(userService)) {
            throw new BusinessException("该服务商不存在");
        }
        user.setService(bo.getService());
        user.setTeamLeader(0);
        this.setUpdateBaseData(user, loginAdmin);
        int i = this.userMapper.updateByPrimaryKeySelective(user);
        if (i == 0) {
            throw new BusinessException("修改团队失败");
        }
        //查询当前用户的推广表
        UserPromotion param = new UserPromotion();
        param.setDeleted(0);
        param.setPUser(bo.getUserID());
        UserPromotion userPromotion = this.userPromotionMapper.selectOne(param);
        //修改推广人信息
        UserPromotion updateInstance = this.getUpdateInstance(UserPromotion.class);
        updateInstance.setUserPromotionID(userPromotion.getUserPromotionID());
        updateInstance.setUserID(userService.getUserID());
        this.setUpdateBaseData(updateInstance,loginAdmin);
        int i1 = this.userPromotionMapper.updateByPrimaryKeySelective(updateInstance);
        if (i1 == 0){
            throw new BusinessException("修改用户推广失败");
        }
        return 1;
    }

    @Override
    public List<UserBalance> balanceRecord(Integer userID) {
        UserBalance userBalance = new UserBalance();
        userBalance.setUserID(userID);
        userBalance.setDeleted(0);
        List<UserBalance> userBalances = this.userBalanceMapper.select(userBalance);
        return userBalances;
    }

    @Override
    public User uptAlipay(BindAlipayBo bo, User loginUser) {
        return this.bindAlipay(bo, loginUser);
    }

    @Override
    public int addCustomer(String customer, User loginUser) {
        User user = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        if (!user.getPosition().equals(UserPositionEnum.FWS.getValue())) {
            throw new BusinessException("仅支持服务商填写客服微信");
        }
        User updateUser = this.getUpdateInstance(User.class);
        updateUser.setUserID(user.getUserID());
        updateUser.setCustomer(customer);
        this.setUpdateBaseData(updateUser, loginUser);
        int i = this.userMapper.updateByPrimaryKeySelective(updateUser);
        if (i == 0) {
            throw new BusinessException("填写客服微信失败");
        }
        return 1;
    }

    @Override
    public int uptRatio(UserUptRatioBo bo, User loginUser) {
        User user = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        if (!user.getPosition().equals(UserPositionEnum.FWS.getValue())) {
            throw new BusinessException("仅支持服务商调整佣金比例");
        }
        ConfigBrokerage configBrokerage = new ConfigBrokerage();
        configBrokerage.setUserID(loginUser.getUserID());
        configBrokerage.setType(0);
        configBrokerage.setDeleted(0);
        ConfigBrokerage configBrokerage1 = this.configBrokerageMapper.selectOne(configBrokerage);
//        ConfigBrokerage configBrokerage1 = this.configBrokerageMapper.selectByPrimaryKey(bo.getConfigBrokerageID());
        if (configBrokerage1.getCaptainProportion() < bo.getDefaultCaptainProportion()){
            throw new BusinessException("团队长比例不能超过："+configBrokerage1.getCaptainProportion()+"%");
        }
        if (configBrokerage1.getCaptainMin() > bo.getDefaultCaptainProportion()){
            throw new BusinessException("团队长比例不能低于："+configBrokerage1.getCaptainMin()+"%");
        }
        if (configBrokerage1.getUserMax() < bo.getDefaultUserProportion()){
            throw new BusinessException("用户比例不能超过："+configBrokerage1.getUserMax()+"%");
        }
        if (configBrokerage1.getUserMin() > bo.getDefaultUserProportion()){
            throw new BusinessException("用户比例不能低于："+configBrokerage1.getUserMin()+"%");
        }
        ConfigBrokerage updateInstance = this.getUpdateInstance(ConfigBrokerage.class);
        updateInstance.setConfigBrokerageID(configBrokerage1.getConfigBrokerageID());
        updateInstance.setDefaultCaptainProportion(bo.getDefaultCaptainProportion());
        updateInstance.setDefaultUserProportion(bo.getDefaultUserProportion());
        int i = this.configBrokerageMapper.updateByPrimaryKeySelective(updateInstance);
        if (i == 0) {
            throw new BusinessException("调整比例失败");
        }
        return 1;
    }

    @Override
    public PageInfo<User> income(PageParam pageParam, User loginUser) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
        pageParam.getKv().put("userID", loginUser.getUserID());
        List<User> users = this.userMapper.income(pageParam.getKv());
        for (User user : users) {
            UserPromotion userPromotion1 = new UserPromotion();
            userPromotion1.setDeleted(0);
            userPromotion1.setPUser(user.getUserID());
            UserPromotion userPromotion = this.userPromotionMapper.selectOne(userPromotion1);
            user.setUserPromotion(userPromotion);
        }
        return new PageInfo<>(users);
    }

    @Override
    public PageInfo<User> addIncome(PageParam pageParam, User loginUser) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
        pageParam.getKv().put("userID", loginUser.getUserID());
        List<User> users = this.userMapper.addIncome(pageParam.getKv());
        return new PageInfo<>(users);
    }

    @Override
    public User getNumber(User loginUser) {
        return this.userMapper.selectByPrimaryKey(loginUser.getUserID());

    }

    @Override
    public int upgradation(UserUpgradeBo bo, User loginUser) {
        User user = this.userMapper.selectByPrimaryKey(bo.getUserID());
        if (BeanUtil.isEmpty(user)) {
            throw new BusinessException("该用户不存在");
        }
        if (user.getPosition().equals(bo.getState())) {
            throw new BusinessException("当前用户已是该级别");
        }
        //查询上级服务商信息
        User user1 = this.userMapper.selectByPrimaryKey(user.getService());

        UserPromotion promotion = new UserPromotion();
        promotion.setPUser(user.getUserID());
        promotion.setDeleted(0);
        UserPromotion userPromotion = this.userPromotionMapper.selectOne(promotion);
        if (BeanUtil.isEmpty(userPromotion)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "用户推广表数据异常");
        }
        UserPromotion updateInstance = this.getUpdateInstance(UserPromotion.class);
        updateInstance.setUserPromotionID(userPromotion.getUserPromotionID());
        if (bo.getState().equals(UserPositionEnum.PT.getValue())) {
            if (!user.getPosition().equals(UserPositionEnum.ZS.getValue())) {
                throw new BusinessException("该用户不是钻石用户不能升级为初级用户");
            }
            user.setPosition(UserPositionEnum.PT.getValue());
            user.setCode(VerifyCodeUtil.generateVerifyCode(6));
            updateInstance.setPosition(UserPositionEnum.PT.getValue());
            updateInstance.setPromotionType(UserPositionEnum.PT.getValue());

        } else if (bo.getState().equals(UserPositionEnum.TDZ.getValue())) {
            if (user.getPosition().equals(UserPositionEnum.ZS.getValue())){
                user.setCode(VerifyCodeUtil.generateVerifyCode(6));
                updateInstance.setPromotionType(UserPositionEnum.PT.getValue());
            }
            user.setPosition(UserPositionEnum.TDZ.getValue());
            user.setTeamLeader(0);
            updateInstance.setPosition(UserPositionEnum.TDZ.getValue());
            user1.setLeftNumber(user1.getLeftNumber() - 1);
            this.userMapper.updateByPrimaryKeySelective(user1);
        }
        else {
            throw new BusinessException("没有该级别");
        }
        this.userPromotionMapper.updateByPrimaryKeySelective(updateInstance);
        this.setUpdateBaseData(user, loginUser);
        int i = this.userMapper.updateByPrimaryKeySelective(user);
        if (i == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "升级失败");
        }
        return 1;
    }

    @Override
    public ConfigBrokerage getRatio(User loginUser) {
        log.info("入参：{}", loginUser);
        User user = this.userMapper.selectByPrimaryKey(loginUser.getUserID());
        if (!user.getPosition().equals(UserPositionEnum.FWS.getValue())) {
            throw new BusinessException("当前级别不能获取佣金比例");
        }
        ConfigBrokerage configBrokerage = new ConfigBrokerage();
        configBrokerage.setDeleted(0);
        configBrokerage.setType(0);
        configBrokerage.setUserID(loginUser.getUserID());
        return this.configBrokerageMapper.selectOne(configBrokerage);
    }

    @Override
    public int payment(Integer userID, BigDecimal amount, SysAdmin loginAdmin) {
        User user = this.userMapper.selectByPrimaryKey(userID);
        if (BeanUtil.isEmpty(user)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "找不到用户信息");
        }
        user.setWallet(user.getWallet().add(amount));
        this.setUpdateBaseData(user, loginAdmin);
        int i = this.userMapper.updateByPrimaryKeySelective(user);
        if (i == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "平台打款失败");
        }
        //新增余额变动记录
        UserBalance userBalance = new UserBalance(
                user.getUserID(),
                user.getWallet(),
                user.getWallet().subtract(amount),
                amount,
                null,
                UserBalanceStatusEnum.PTDK.getValue(),
                null,
                "平台打款"
        );
        this.setCreateBaseData(userBalance, loginAdmin);
        int i1 = this.userBalanceMapper.insertSelective(userBalance);
        if (i1 == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "新增余额变动记录失败");
        }
        return 1;
    }

    @Override
    public User uptTzdNumber(User user, SysAdmin loginSysAdmin) {
        User userParam = this.userMapper.selectByPrimaryKey(user.getUserID());
        if (BeanUtil.isEmpty(userParam)) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "用户信息不存在");
        }
        //获取当前已使用的团队长名额
        int ysyNumber = userParam.getTdzNumber() - userParam.getLeftNumber();
        if (user.getTdzNumber() < ysyNumber) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "当前修改的团队长数量小于已使用团队长数量");
        }
        userParam.setTdzNumber(user.getTdzNumber());
        userParam.setLeftNumber(user.getTdzNumber() - ysyNumber);
        this.setUpdateBaseData(userParam, loginSysAdmin);
        int i = this.userMapper.updateByPrimaryKeySelective(userParam);
        if (i == 0) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "修改团队长数量失败");
        }
        return userParam;
    }

    @Override
    public GetUserNumberVo getUserNumber(SysAdmin admin) {
        GetUserNumberVo vo = null;
        SysAdmin sysAdmin = this.sysAdminMapper.selectByPrimaryKey(admin.getSysAdminID());
        if (sysAdmin.getUserType().equals("01")) {
            User user = new User();
            user.setDeleted(0);
            user.setPhone(sysAdmin.getPhonenumber());
            User param = this.userMapper.selectOne(user);

            UserPromotion userPromotion = new UserPromotion();
            userPromotion.setUserID(param.getUserID());
            userPromotion.setDeleted(0);
            List<UserPromotion> select = this.userPromotionMapper.select(userPromotion);
            //递归查询所有间接用户
            List<Integer> userIDList = new ArrayList<>();
            for (UserPromotion promotion : select) {
                this.userService.queryUserID(userIDList, promotion.getPUser());
            }
            userIDList.add(param.getUserID());
//            String userIDs = userIDList.stream().map(Object::toString).collect(Collectors.joining(","));
            vo = this.userMapper.getUserNumber1(param.getUserID());
        } else {
            vo = this.userMapper.getUserNumber();
        }
        return vo;
    }

    @Override
    public List<GetUserVo> getRegisterNumber(String time, SysAdmin admin) {
        String userIDs = "";
        admin = this.sysAdminService.selectUserById(admin.getSysAdminID());
        if (admin.getUserType().equals("01")) {
            User user = new User();
            user.setDeleted(0);
            user.setPhone(admin.getPhonenumber());
            User param = this.userMapper.selectOne(user);

            UserPromotion userPromotion = new UserPromotion();
            userPromotion.setUserID(param.getUserID());
            userPromotion.setDeleted(0);
            List<UserPromotion> select = this.userPromotionMapper.select(userPromotion);
            //递归查询所有间接用户
            List<Integer> userIDList = new ArrayList<>();
            for (UserPromotion promotion : select) {
                this.userService.queryUserID(userIDList, promotion.getPUser());
            }
            userIDList.add(param.getUserID());
            userIDs = userIDList.stream().map(Object::toString).collect(Collectors.joining(","));
        }
        return this.userMapper.getRegisterNumber(time, userIDs);
    }

    @Override
    public MyTem getMyTeamTotal(User loginUser) {
        UserPromotion userPromotion = new UserPromotion();
        userPromotion.setUserID(loginUser.getUserID());
        userPromotion.setDeleted(0);
        int i = this.userPromotionMapper.selectCount(userPromotion);
        int total = this.userPromotionMapper.selectTotal(loginUser.getUserID());
        int TDZNum = this.userMapper.getTDZNum(loginUser.getUserID());
        MyTem myTem = new MyTem();
        myTem.setNum(i);
        myTem.setTotal(total);

        //获取到所有直接用户ID
        List<UserPromotion> select = this.userPromotionMapper.select(userPromotion);
        //递归查询所有间接用户
        List<Integer> userIDList = new ArrayList<>();
        for (UserPromotion promotion : select) {
            this.queryUserID(userIDList, promotion.getPUser());
        }
        myTem.setJjNum(userIDList.size());
        myTem.setTDZNum(TDZNum);
        return myTem;
    }

    @Override
    public List<User> getMyTuz(User loginUser) {
        User user = new User();
        user.setService(loginUser.getUserID());
        user.setPosition(3);
        user.setDeleted(0);
        return this.userMapper.select(user);
    }

    @Override
    public BigDecimal getMoney(User loginUser) {
        return this.userBalanceMapper.getMoney(loginUser.getUserID());
    }

    @Override
    public BigDecimal getYXMoney(User loginUser) {
        return this.userBalanceMapper.getYXMoney(loginUser.getUserID());
    }

    @Override
    public BigDecimal getRWMoney(User loginUser) {
        if(loginUser.getUserID().equals(6)){
            return this.userBalanceMapper.getRWMoney(loginUser.getUserID()).add(new BigDecimal(315348));
        }
        return this.userBalanceMapper.getRWMoney(loginUser.getUserID());
    }

    @Override
    public BigDecimal getKCMoney(User loginUser) {
        return this.userBalanceMapper.getKCMoney(loginUser.getUserID());
    }

    @Override
    public PageInfo<UserWalletDetailVo> getKCDetail(PageParam pageParam, User loginUser) {
        PageHelper.startPage(pageParam.getPage(), pageParam.getPageSize());
        pageParam.getKv().put("userID", loginUser.getUserID());
        List<UserWalletDetailVo> vos = this.userBalanceMapper.getKC(pageParam.getKv());
        return new PageInfo<>(vos);
    }

    /**
     * 随机获取6位短信数字验证码
     *
     * @return
     */
    public static String getSmsVerifyCode() {
        Random random = new Random();
        String code = "";
        for (int i = 0; i < 6; i++) {
            int rand = random.nextInt(10);
            code += rand;
        }
        return code;
    }

    public static void sendAliSms(String phone, String smsCode) {
        log.info("调用阿里短信接口开始 {}", smsCode);
        try {
            com.aliyun.dysmsapi20170525.Client client = Sample
                    .createClient(SmsConfig.accessKeyId, SmsConfig.accessKeySecret);
            com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                    .setSignName("悦推客")
                    .setTemplateCode(SmsConfig.templateCode)
                    .setPhoneNumbers(phone)
                    .setTemplateParam("{\"code\":\"" + smsCode + "\"}");
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            com.aliyun.dysmsapi20170525.models.SendSmsResponse resp = client.sendSmsWithOptions(sendSmsRequest, runtime);
            com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp)));
            log.info("调用阿里短信接口结束{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp)));
        } catch (Exception e) {
            throw new BusinessException(ResponseCodeEnum.ERROR, "短信发送失败");
        }
    }
}
